GET /api/users 或 DELETE /api/todos/1。但在真實世界中,刪除任務或修改個人資料,必須是「登入後的本人」才能操作。JWT 是一串看起來像亂碼的字串(通常長這樣:xxxxx.yyyyy.zzzzz),它由三個部分組成,中間用句號 . 隔開:
userId: 99)、權限等級 (role: "admin") 以及通行證的過期時間。userId: 99 改成 userId: 1 (試圖偽裝成老闆),伺服器一驗證簽章就會發現被篡改,直接拒絕請求。我們將使用業界最通用的 jsonwebtoken 套件。
請在專案中安裝:npm install jsonwebtoken
在資料夾下新增一個 auth-demo.js,輸入以下程式碼:
import jwt from 'jsonwebtoken';
// 這是伺服器的最高機密,絕對不能外流!(實務上會放在 .env 檔案裡,明天會教)
const SECRET_KEY = "my_super_secret_key_dont_tell_anyone";
// 模擬:1. 登入成功,核發 JWT 通行證
const loginAndGenerateToken = () => {
// 假設使用者帳密輸入正確,我們從資料庫查到他的 ID 是 101
const userData = {
userId: 101,
username: "Bibo",
role: "user"
};
// 使用 jwt.sign(內容, 密鑰, 設定選項) 來產生 Token
const token = jwt.sign(
userData,
SECRET_KEY,
{ expiresIn: '1h' } // 設定 1 小時後過期
);
console.log(" 成功核發 Token:\n", token, "\n");
return token;
};
// 模擬:2. 使用者帶著 Token 來請求受保護的 API
const verifyUserToken = (clientToken) => {
try {
// jwt.verify() 會自動檢查:1. 簽章是否正確 2. 是否過期
const decodedPayload = jwt.verify(clientToken, SECRET_KEY);
console.log(" 驗證成功!歡迎回來,使用者:", decodedPayload.username);
console.log("你的完整 Payload:", decodedPayload);
} catch (error) {
// 常見錯誤包含:JsonWebTokenError (簽章錯誤/被篡改)、TokenExpiredError (已過期)
console.error(" 驗證失敗,請重新登入!錯誤原因:", error.message);
}
};
// --- 執行測試 ---
console.log("--- 模擬登入流程 ---");
const myToken = loginAndGenerateToken();
console.log("\n--- 模擬拿著正確的 Token 去請求 API ---");
verifyUserToken(myToken);
console.log("\n--- 模擬駭客拿著被篡改的 Token 去請求 API ---");
const fakeToken = myToken + "hack"; // 故意破壞 Token 結構
verifyUserToken(fakeToken);
請永遠記住一件事:JWT 的 Payload 只是經過 Base64 編碼,並沒有加密!
任何人拿到你的 Token,都可以去 jwt.io 網站把 Payload 的內容完全解碼看光光。
絕對、絕對、絕對不可以把使用者的「密碼」、「信用卡號」等敏感資訊塞進 Payload 裡面!Payload 只適合放 id 或 role 這種用來識別身分的不敏感資料。